package util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;

import org.apache.commons.io.FileUtils;

public class FileUtil {
	public static final int BUFFER_SIZE = 128*1024;
	
	public static void saveFile(String path, byte[] contents) {
		FileOutputStream fos;
		try {
			fos = new FileOutputStream(path);
			fos.write(contents);
			fos.close();
		} catch (Exception e) {
			System.out.println("An exception thrown while saving stream to file");
			e.printStackTrace();
		}
	}
	
	public static void saveFile(String path, String contents) {
		File file = new File(path);
		BufferedWriter writer = null;
		try {
		    writer = new BufferedWriter(new FileWriter(path));
		    writer.write(contents);
		}
		catch (IOException e) {
			System.out.println("An error occured while writing to file");
		}
		finally	{
		    try {
		        if (writer != null)
		        writer.close();
		    }
		    catch (IOException e) {
		    }
		}
	}
	
	public static byte[] readFile(String path) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		try {
			copyStream(new FileInputStream(path), baos, BUFFER_SIZE);
		} catch (Exception e) {
			System.out.println("An error catcher while copying the stream");
			e.printStackTrace();
		}
		byte[] bytes = baos.toByteArray();
		return bytes;
	}
	
	public static boolean deleteFile(String path) {
		File file = new File(path);
		return file.delete();
	}
	
	public static String getFileContents(String path) {
		return getFileContents(new File(path));
	}
	
	public static String getFileContents(File file) {
		String contents = "";
		BufferedReader br = null;
		try {
	    	br = new BufferedReader(new FileReader(file));
			StringBuilder sb = new StringBuilder();
	        String line = br.readLine();
	        while (line != null) {
	            sb.append(line);
	            sb.append('\n');
	            line = br.readLine();
	        }
	        contents = sb.toString();
	    } catch (Exception e) {
	    	System.out.print("An exception catched while trying to read a file");
    		e.printStackTrace();
    	} finally {
	    	try {
	    		br.close();
	    	} catch (Exception e) {
	    		System.out.print("An exception catched while trying to close a file");
	    		e.printStackTrace();
	    	}
	    }
		return contents;
	}
	
	public static File getFile(String filePath) {
		return null;
	}
	
	public static boolean pathExists(String url) {
		return new File(url).exists();
	}
	
	public static boolean createDirectory(String dir) {
		boolean dirCreated = (new File(dir)).mkdirs();
		return dirCreated;
	}
	
	public static void copyStream(InputStream input, OutputStream output, int bufferSize) throws IOException {
		byte[] buf = new byte[bufferSize];
		int bytesRead = input.read(buf);
		while (bytesRead != -1) {
			output.write(buf, 0, bytesRead);
			bytesRead = input.read(buf);
		}
		output.flush();
	}
	
	public static boolean downloadFile(String URL, String filePath) {
		try {
			URL url = new URL(URL);
			/** Some of the web resources restrict access to papers for client applications, which results in HTTP 403 response. 
			 *  Here we try to trick the server side, making the request similar to a browser's **/
			HttpURLConnection con = (HttpURLConnection) url.openConnection();
		    con.addRequestProperty("User-Agent", "Mozilla/5.0");
		    
		    InputStream is = con.getInputStream();
			OutputStream os = new FileOutputStream(filePath);
			
			byte[] b = new byte[2048];
			int length;

			while ((length = is.read(b)) != -1) {
				os.write(b, 0, length);
			}
			is.close();
			os.close();
			return true;

		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		return false;
	}
	
	/** TODO: test this **/
	public static void deleteDirectory(String directory) {
	    File dir = new File(directory);
		try {
			FileUtils.deleteDirectory(dir);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	
}
